package cn.zymall.scheduled.task;

import cn.zymall.common.model.SysTask;
import cn.zymall.common.utils.redis.RedisUtil;
import cn.zymall.common.utils.time.TimeUtil;
import cn.zymall.scheduled.service.TaskService;
import lombok.SneakyThrows;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.sql.*;
import java.util.Date;

/**
 * @author xuxianda
 * @Description: 定时任务
 * 目前只考虑单机下线程安全
 * @date 2020/8/19 19:57
 * @Copyright
 * @return
 **/
@Component
@EnableScheduling
@EnableAsync
public class ScheduleTask {

    @Autowired
    TaskService taskService;

    @Autowired
    SqlSessionFactory sqlSessionFactory;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    TimeUtil timeUtil;


    /**
     * 异步执行
     * 处理单次定时任务 (TASK_STATUS = 1)
     * 每10秒去扫描一次
     */
    @Async
    @Scheduled(fixedDelay = 10000)
    public void putaway() {
        try {
            SysTask sysTask = taskService.selectWaitTask();
            /**
             * 判断sysTask 对象是否为空
             */
            if (sysTask == null) {
                return;
            }
            System.out.println(sysTask);
            /**
             * 计算两个时间间隔多少毫秒，如果还剩60000毫秒(1分钟)，就将新建线程并等待60000毫秒执行
             */
            long millForDateTimeDouble = timeUtil.getMillForDateTimeDouble(sysTask.getTaskTime(), new Date());
            if (millForDateTimeDouble == 60000 || millForDateTimeDouble < 60000) {
                System.out.println("找到即将开始的任务");
                Runnable r1 = new Runnable() {
                    @Override
                    public void run() {
                        sysTask.setTaskStatus(1);
                        taskService.updateById(sysTask);
                    }
                };
                new Thread(r1).start();
                /**
                 * 新建一个线程，用来执行sql
                 */
                Runnable r2 = new Runnable() {
                    @SneakyThrows
                    @Override
                    public void run() {
                        /**
                         * 应该耗费了一点点时间吧
                         */
                        Thread.sleep(millForDateTimeDouble - 200);
                        System.out.println("进入run");
                        Connection connection = null;
                        Statement statement = null;
                        try {
                            /**
                             * 获取连接 执行sql
                             */
                            connection = sqlSessionFactory.openSession().getConnection();
                            statement = connection.createStatement();
                            ResultSet resultSet = statement.executeQuery(sysTask.getTaskSql());
                            while (resultSet.next()) {
                                /**
                                 * 调试使用的
                                 */
                                System.out.println(resultSet);
                            }
                            sysTask.setTaskStatus(1);
                        } catch (SQLException throwables) {
                            throwables.printStackTrace();
                            /**
                             * 处理失败 将状态改为 -1（处理失败）
                             */
                            sysTask.setTaskStatus(-1);
                        } finally {
                            /**
                             * 依次关闭连接
                             */
                            taskService.updateById(sysTask);
                            statement.close();
                            connection.close();
                        }
                    }
                };
                Thread thread = new Thread(r2);
                thread.run();
            }
        } catch (Exception e) {
            System.err.println("扫描任务表时出现异常");
            e.printStackTrace();
            /**
             * 程序结束
             */
//            System.exit(0);
        } finally {
            /**
             * 这里写别的杂七杂八的逻辑，空着也没事
             */
        }
    }

    /**
     * 广告定时任务，定时投放广告
     */
    @Async
    @Scheduled(fixedDelay = 10000)
    public void adTask() {

    }


}
